/**
 * 
 */
package process;

import java.util.Vector;

import process.models.ClusterEnsemble;
import process.models.Clusterer;
import process.models.KMeans;
import util.Timer;
import data.Distance;
import data.EuclideanDistance;
import data.SimilaritySet;

/**
 * @author yexijiang
 * @date Jul 31, 2008
 */
public class TagClusterEnsemble
{
	private int m_NumOfCandidateTags;
	private int m_EnsembleCluster;	//	number of clusters in final result
	private int m_NumOfClusterers;
	private int m_Sequence[];

	private SimilaritySet m_Set[];
	private ClusterEnsemble m_Ensemble[];
	
	private Vector<String> m_Clusters[][];
	
	
	public TagClusterEnsemble(int numOfCandidateTags, int recordsForEachTag, int ensembleCluster, int[] sequence, int numOfClusterers)
	{
		m_NumOfCandidateTags = numOfCandidateTags;
		m_EnsembleCluster = ensembleCluster;
		m_NumOfClusterers = numOfClusterers;
		m_Sequence = sequence;
		m_Clusters = new Vector[m_NumOfCandidateTags][m_EnsembleCluster];
		PreProcess preProcess = new PreProcess(numOfCandidateTags, sequence, recordsForEachTag);
		m_Set = preProcess.preProcess();
	}
	
	public Vector<String>[][] doEnsemble()
	{
		long startTime = Timer.startRecord();
		m_Ensemble = new ClusterEnsemble[m_Set.length];
		for(int i = 0; i < m_Set.length; ++i)
		{
			m_Ensemble[i] = new ClusterEnsemble(m_Set[i], m_Sequence,
					m_Set[i].getKeys(), m_EnsembleCluster);
			Distance dist = new EuclideanDistance();
			Clusterer[] kmeans = new Clusterer[m_NumOfClusterers];

			for (int j = 0; j < kmeans.length; ++j) 
			{
				int numOfCluster = (int)Math.sqrt(m_Set[i].size());
				kmeans[j] = new KMeans(m_Sequence, numOfCluster, m_Set[i], m_Set[i].getKeys(), dist);
				m_Ensemble[i].addClusterer(kmeans[j]);
			}
			m_Clusters[i] = m_Ensemble[i].doEnsemble();
		}
		long endTime = Timer.endRecord(startTime);
		System.out.println("The time clustering ensemble use is:" + endTime);
		return m_Clusters;
	}
	
	public Vector<String> getTargetTags()
	{
		Vector<String> targetTags = new Vector<String>();
		for(int i = 0; i < m_Set.length; ++i)
		{
			targetTags.add(m_Set[i].getTargetTag());
		}
		return targetTags;
	}
	
	public static void main(String[] args)
	{
		int sequence[] = {1,2,3,4,5,6,7,8};
		int numOfCandidateTags = 100;
		int recordsForEachTag = 10;
		int numOfClusterer = 5;
		int ensembleCluster = 5;
		for(int i = 1; i < 10; ++i)
		{
			numOfClusterer = (i + 1);
			System.out.println("Experiment " + i + ":");
			TagClusterEnsemble ensemble = new TagClusterEnsemble(numOfCandidateTags, recordsForEachTag, ensembleCluster, sequence, numOfClusterer);
			ensemble.doEnsemble();
		}
	}
}
